Tutorial step 3: building the DLL and testing the filter

We have all that's necessary for a bare VirtualDub filter, and in fact, if this were an internal filter, all that would be left is to add the filterDef_tutorial structure to the list in f_list.cpp. However, for this filter to be loaded externally, we need to add the necessary DLL framework.

Module load and unload functions

VirtualDub requires that filter DLLs export two functions:

extern "C" int __cdecl VirtualdubFilterModuleInit2(FilterModule *fm, const FilterFunctions *ff, int& vdfd_ver, int& vdfd_compat);
extern "C" void __cdecl VirtualdubFilterModuleDeinit(FilterModule *fm, const FilterFunctions *ff);

These functions must be exported undecorated, that is, not as _VirtualdubFilterModuleInit@12 or some mess of C++ decorations. Note also at the functions start with Virtualdub, with the second d uncapitalized.

The purpose of the init routines is to add/remove filters from VirtualDub's global list when the DLL loads and unloads, and to perform any necessary module-level initialization. Preferably, module-level initialization should be kept to a minimum to reduce resource usage when the module's filters are loaded but unused. Usually, the init/deinit functions need only call ff->addFilter() and ff->removeFilter().

The init function returns non-zero on failure, but VirtualDub does not remove any filters you have already added. With multiple filters, you must back out any filters you have already added if you wish to fail because not all filters could be loaded.

Init functions also have one other purpose: they allow VirtualDub to detect if a filter uses an old, incompatible interface.  The vdfd_ver variable holds the current interface version, and the vdfd_compat holds the earliest version that this build of VirtualDub is backwards compatible with.  Before returning, set them with the versions in your header files:

    vdfd_ver    = VIRTUALDUB_FILTERDEF_VERSION;
    vdfd_compat = VIRTUALDUB_FILTERDEF_COMPATIBLE;

If your filter uses an interface version which the current version of VirtualDub cannot support, VirtualDub will abort the filter load and notify the user.


VIRTUALDUB_FILTERDEF_COMPATIBLE specifies the minimum version of VirtualDub that can handle the basic filter API.  This does not mean that all functions specified in the header file are available.  If you use features that are not supported in API V4 (V1.2), you must either hardcode a higher API level for vdfd_compat, or check vdfd_ver and avoid calling functions if they are not provided by the host.

Creating the load and unload functions for the tutorial filter

Because tutorial only has one filter in its module, the functions are fairly straightforward:

extern "C" int __declspec(dllexport) __cdecl VirtualdubFilterModuleInit2(FilterModule *fm, const FilterFunctions *ff, int& vdfd_ver, int& vdfd_compat);
extern "C" void __declspec(dllexport) __cdecl VirtualdubFilterModuleDeinit(FilterModule *fm, const FilterFunctions *ff);

static FilterDefinition *fd_tutorial;

int __declspec(dllexport) __cdecl VirtualdubFilterModuleInit2(FilterModule *fm, const FilterFunctions *ff, int& vdfd_ver, int& vdfd_compat) {
    if (!(fd_tutorial = ff->addFilter(fm, &filterDef_tutorial, sizeof(FilterDefinition))))
        return 1;

    vdfd_ver    = VIRTUALDUB_FILTERDEF_VERSION;
    vdfd_compat = VIRTUALDUB_FILTERDEF_COMPATIBLE;

    return 0;
}

void __declspec(dllexport) __cdecl VirtualdubFilterModuleDeinit(FilterModule *fm, const FilterFunctions *ff) {
    ff->removeFilter(fd_tutorial);
}

Because the FilterDefinition structure may expand later, VirtualDub returns a new definition pointer when the filter is added. This pointer is the structure that VirtualDub uses, and is the one that needs to be passed to the removeFilter function.

Building and testing the filter

Create a new Win32 DLL project if you haven't already, and throw all the code so far into a file along with #include "filters.h". Compile and build a DLL file out of it, and rename the output DLL to tutorial.vdf. Now load VirtualDub, select Video > Filters. Click Add..., and then Load... to load the filter. If you're lucky, the filter will appear on the list, and you can use it to process video files!

[up] back to main page
[prev] tutorial[2]: creating the FilterDefinition structure
[next] tutorial[4]: stop and start routines


VirtualDub external filter SDK 1.05©1999-2001 Avery Lee <phaeron@virtualdub.org>